home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
print
/
uplabel.zip
/
GETARG.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-12-19
|
4KB
|
183 lines
/*
getarg.c
Written by D'Arcy J.M. Cain
D'Arcy Cain Consulting
275 Manse Road, Unit # 24
West Hill, Ontario
M1E 4X8
416 281 6094
UUCP: darcy@druid
This routine may be freely distributed as long as credit is given to D'Arcy
J.M. Cain, the source is included and this notice remains intact. There is
specifically no restrictions on use of the program including personal or
commercial. You may even charge others for this routine as long as the above
conditions are met.
This is not shareware and no registration fee is expected. If you like the
program and want to support this method of distribution, write a program or
routine and distribute it the same way and I will feel I have been paid.
Of course gifts of money, drinks and extravagant jewels are always welcome.
*/
#ifdef BSD
#include <strings.h>
#else
#include <string.h>
#define index strchr
#endif
#include <stdlib.h>
#include <malloc.h>
#include <ctype.h>
#ifndef NULL
#define NULL (void *)(0)
#endif
int optind = 0;
char *optarg;
/* Note that the above declarations can cause problems with programs
that use getopt(3) if this module is scanned first in the link phase.
This means that if you use getopt sometimes then you should keep this
module separate and link it in specifically when needed. Alternatively
you can change the names of the above externs (perhaps declare optind as
static as programs don't really need it anyway) and have a #define so
that the program still uses the above name(s). I considered using a
different name for optarg but was afraid that anything I picked would
conflict with user's names.
*/
static char **pargv = NULL;
static int pargc = 0;
int initarg(int argc, char **argv)
{
int k = argc * sizeof(char *);
/* check for trivial case */
if (!argc)
return(0);
/* get or expand space */
if (pargc == 0)
pargv = malloc(k);
else
pargv = realloc(pargv, pargc + k);
if (pargv == NULL)
return(-1); /* not enough memory for argument pointers */
/* if adding arguments insert them at current argument */
if (pargc)
for (k = pargc - 1; k >= optind; k--)
pargv[k + argc] = pargv[k];
for (k = 0; k < argc; k++)
pargv[optind + k] = argv[k];
pargc += argc;
return(pargc);
}
/*
The meat of the module. This returns options and arguments similar to
getopt() as described above.
*/
int getarg(const char *opts)
{
static int sp = 0, end_of_options = 0;
int c;
char *cp;
optarg = NULL;
/* return 0 if we have read all the arguments */
if(optind >= pargc)
{
if (pargv != NULL)
free(pargv);
pargv = NULL;
pargc = 0;
optind = 0;
return(0);
}
/* Are we starting to look at a new argument? */
if(sp == 0)
{
/* return it if it is a file name */
if ((*pargv[optind] != '-') || end_of_options)
{
optarg = pargv[optind++];
return(-1);
}
/* special return for standard input */
if (strcmp(pargv[optind], "-") == 0)
{
optind++;
return('-');
}
/* "--" signals end of options */
if (strcmp(pargv[optind], "--") == 0)
{
end_of_options = 1;
optind++;
return(getarg(opts));
}
/* otherwise point to option letter */
sp = 1;
}
else if (pargv[optind][++sp] == 0)
{
/* recursive call if end of this argument */
sp = 0;
optind++;
return(getarg(opts));
}
c = pargv[optind][sp];
if(c == ':' || (cp = index(opts, c)) == NULL)
return('?');
if(*++cp == ':')
{
/* Note the following code does not allow leading
spaces or all spaces in an argument */
while (isspace(pargv[optind][++sp]))
;
if(pargv[optind][sp])
optarg = pargv[optind++] + sp;
else if(++optind >= pargc)
c = '?';
else
optarg = pargv[optind++];
sp = 0;
}
else if (*cp == ';')
{
while (isspace(pargv[optind][++sp]))
;
if (pargv[optind][sp])
optarg = pargv[optind] + sp;
optind++;
sp = 0;
}
return(c);
}